package model

import (
	_ "github.com/jinzhu/gorm/dialects/postgres"
	"time"
)

type Allow struct {
	Type string   `json:"type"`
	Keys []uint64 `json:"keys"`
}

type Itembank struct {
	ID        uint64     `json:"id" gorm:"primary_key"`
	Creator   uint64     `json:"creator" gorm:"not null;"`
	Users     []User     `json:"users" gorm:"many2many:itembank_users;"`
	Groups    []Group    `json:"groups" gorm:"many2many:itembank_groups;"`
	Tags      []Tag      `json:"tags" gorm:"many2many:itembank_tags;"`
	Questions []Question `json:"questions" gorm:"many2many:itembank_questions;"`
	Name      string     `json:"name" gorm:"not null;unique;"`
	Limited   bool       `json:"limited" gorm:"not null;"` //是否受限制，如果受限制，则根据AuthorityType判断授权给谁可访问
	AllowType string     `json:"allow_type" `              //授权给 用户、组、标签
	Disable   bool       `json:"disable" gorm:"not null;"` //是否启用
	Image     string     `json:"image"`
	CreatedAt time.Time
	UpdatedAt time.Time
}

func (t *Itembank) Update() (err error) {
	tx := mydb.Begin()
	// update or create
	err = tx.Save(&t).Error
	if err != nil {
		tx.Rollback()
		return err
	}
	tx.Commit()
	return nil
}


func (t *Itembank) Save(keys []uint64) (err error) {
	tx := mydb.Begin()
	// update or create
	if t.ID > 0 {
		err = tx.Save(&t).Error
	} else {
		err = tx.Create(&t).Error
	}

	if err != nil {
		tx.Rollback()
		return err
	}

	t.RemoveAssociation(t.ID)
	if t.Limited != false {
		switch t.AllowType {
		case "groups":
			var groups []Group
			for _, id := range keys {
				groups = append(groups, Group{ID: id})
			}
			err = tx.Model(&t).Association("Groups").Append(groups).Error
		case "users":
			var users []User
			for _, id := range keys {
				users = append(users, User{ID: id})
			}
			err = tx.Model(&t).Association("Users").Append(users).Error
		case "tags":
			var tags []Tag
			for _, id := range keys {
				tags = append(tags, Tag{ID: id})
			}
			err = tx.Model(&t).Association("Tags").Append(tags).Error
		}
	}
	if err != nil {
		tx.Rollback()
		return err
	}

	tx.Commit()

	return nil
}

func (t Itembank) SaveQuestions(questions []uint64) (err error) {
	tx := mydb.Begin()
	var qs []Question
	for _, id := range questions {
		qs = append(qs, Question{ID: id})
	}

	tx.Model(&t).Association("Questions").Clear()
	err = tx.Model(&t).Association("Questions").Append(qs).Error

	if err != nil {
		tx.Rollback()
		return err
	}

	tx.Commit()

	return nil
}

func (t Itembank)DeleteQuestions(questions []uint64) (err error) {
	tx := mydb.Begin()

	var qs []Question
	for _, id := range questions {
		qs = append(qs, Question{ID: id})
	}

	if err = tx.Model(&t).Association("Questions").Delete(qs).Error ;err != nil {
		tx.Rollback()
		return err
	}

	tx.Commit()
	return nil
}


func (t Itembank) Get() (item Itembank) {
	mydb.Select("id,creator,name,limited,disable,image,allow_type").First(&item, t.ID)
	switch item.AllowType {
	case "groups":
		mydb.Model(&item).Association("Groups").Find(&item.Groups)
	case "users":
		mydb.Model(&item).Select("id,email").Association("Users").Find(&item.Users)
	case "tags":
		mydb.Model(&item).Association("Tags").Find(&item.Tags)
	}

	mydb.Model(&item).Association("Questions").Find(&item.Questions)
	return item
}

func (t Itembank) GetRelatedQuestions() (qs []Question) {
	mydb.Model(&t).Association("Questions").Find(&qs)
	return qs
}

func (t Itembank) GetAll() []Itembank {
	ibs := []Itembank{}
	fields_str := "id,name,disable,limited,image,allow_type" //默认情况下请求的字段

	mydb.Select(fields_str).Find(&ibs)
	return ibs
}

func (t Itembank) IsCreator(userid uint64, bankid uint64) bool {
	mydb.Where("id = ?", bankid).Find(&t)
	if t.Creator == userid {
		return true
	} else {
		return false
	}
}

func (t Itembank) RemoveAssociation(bankid uint64) error {
	mydb.Model(&t).Association("Users").Clear()
	mydb.Model(&t).Association("Groups").Clear()
	mydb.Model(&t).Association("Tags").Clear()
	return nil
}

func (t Itembank) Remove(bankid uint64) error {
	t.ID = bankid
	t.RemoveAssociation(bankid)
	mydb.Delete(&t)
	return nil
}

func (t Itembank) SetEnable(bankid uint64) error {
	t.ID = bankid
	mydb.Model(&t).Where("id = ?", bankid).Update("disable", true)
	return nil
}

func (t Itembank) SetDisable(bankid uint64) error {
	t.ID = bankid
	if err := mydb.Model(&t).Where("id = ?", bankid).Update("disable", t.Image).Error; err != nil {
		return err
	}

	return nil
}

func (t Itembank) SaveImage() error {
	if err :=  mydb.Model(&t).Where("id = ?", t.ID).Update("image", false).Error; err != nil {
		return err
	}

	return nil
}